home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 11 / Cream of the Crop 11-1.iso / database / mmu_gt10.zip / QSORT3.ZIP / QSORT.DOC < prev    next >
Text File  |  1987-03-12  |  26KB  |  524 lines

  1.                          QSORT - Version 3.00
  2.    Copyright (c) 1985, 1986, 1987 - Ben Baker - All rights reserved
  3.  
  4.  
  5.  
  6. QSORT may be freely copied and distributed.  provided that  1)  it  is
  7. distributed  under  the  name  "QSORT," and 2) this documentation file
  8. always  accompanies  it.   Vendors   wishing   to   distribute   QSORT
  9. commercially,  or  with  commercial products may contact the author at
  10. the address below for terms.
  11.  
  12. QSORT is made available under the "share-ware" concept.  If  you  find
  13. this program useful, you are asked to send its author a license fee of
  14. $20 for each machine on which you use it.   This  will  encourage  the
  15. development of other useful, affordable tools.  Send checks to:
  16.  
  17.                          Ben Baker
  18.                          RR #1, Box 637
  19.                          E. Alton, Il 62024
  20.  
  21. Bug  reports  or  suggestions  may be sent to the above address or via
  22. FidoNet mail to Fido node # 100/76, Baker's Acre, or by  logging  into
  23. Baker's Acre BBS at 618-251-2169.
  24.  
  25.  
  26.                          --- INTRODUCTION ---
  27.  
  28. QSORT  was first designed to be a replacement for, and to overcome the
  29. limitations of DOS SORT, but has been enhanced a number of  times  and
  30. moved  to  new  compilers  twice.  The current version will sort files
  31. whose size is limited only by available disk space.  File name(s)  may
  32. be given explicitly or QSORT will sort from standard input to standard
  33. output, and so, may be used in pipes or  with  redirection.   Multiple
  34. key  fields  may be specified.  Binary files with fixed-length records
  35. may be sorted, provided only that keys are ASCII fields.
  36.  
  37. QSORT tries to be very protective of your data.  If QSORT has an error
  38. of  any  kind, it will terminate with the input file still intact, and
  39. will return to DOS with  ERRORLEVEL  =  1.   When  QSORT  successfully
  40. completes  a  sort,  it terminates with ERRORLEVEL set to 0.  (See the
  41. batch commands in your DOS manual for more information on ERRORLEVEL.)
  42.  
  43. The command line syntax is a super-set of SORT's, so QSORT may be used
  44. without other changes in batch files using SORT, but in most cases you
  45. will probably want to make use of QSORT's greater capabilities.
  46.  
  47.  
  48.                 --- The QSORT Command and Options ---
  49.  
  50. QSORT is invoked with the following command:
  51.  
  52.      QSORT [<in_file> [<out_file>]] [/<key_spec>. . .]
  53.                        [/T[<tag>] | /F<len>]  [/R] [/S] [/?]
  54.  
  55. Note that all parameters on the command line are optional.
  56.  
  57. The <in_file> and <out_file> parameters are "ASCII-Z" file specifiers.
  58. They may contain disk and path information in the standard DOS format, 
  59. but must not contain "wild-card" characters.
  60.  
  61. If  <in_file>  is missing, QSORT sorts from standard input to standard
  62. output.  These are files defined and opened by  DOS  before  QSORT  is
  63. loaded.   (See  your DOS  manual concerning the use of redirection and
  64. pipes.)
  65.  
  66. If <in_file> is given but  <out_file>  is  missing,  QSORT  creates  a
  67. temporary  file in the directory containing <in_file> and sorts to the
  68. temporary file.  On successful completion of the  sort,  <in_file>  is
  69. deleted  and  the temporary is renamed to <in_file>.  The effect is an
  70. apparent "sort-in-place."
  71.  
  72. If both file names are given, <in_file> is unchanged  and  the  sorted
  73. output  is  written  to <out_file>.  This feature was added in version
  74. 3.00 as a convenience.  New DOS users sometimes have  difficulty  with
  75. the  concept of redirection.  Note that the following two commands are
  76. exactly equivalent:
  77.  
  78.      QSORT  FILE.TXT  FILE.SRT
  79.      QSORT <FILE.TXT >FILE.SRT
  80.  
  81. In the first, QSORT opens the files.  In the  second,  redirection  is
  82. specified  and DOS opens the files.  The result is the same.  It is an
  83. error QSORT can't detect if you mix these.  For instance:
  84.  
  85.      QSORT  FILE.TXT >FILE.SRT
  86.  
  87. will result in a sort-in-place.  QSORT will open  FILE.TXT  but  won't
  88. know DOS has opened FILE.SRT for it, and will ignore it.
  89.  
  90.                       The /<key_spec> Parameter
  91.  
  92. Up  to 30 /<key_spec> parameters may be used to specify key fields and
  93. are ordered major to  minor  from  left  to  right.   The  /<key_spec>
  94. argument has the form:
  95.  
  96.      /[L][+|-][col][:width]
  97.  
  98. Note  that  all elements of this argument are "optional," but at least
  99. one element must be present following the slant-bar (/).  The 'L',  if
  100. present, specifies "lexical" sequence for this field.  (See discussion
  101. of lexical sequence below.) The minus (-) sign specifies reverse order
  102. for  this field.  The plus (+) sign (or no sign) specifies normal sort
  103. order.  If present, [col] defines the beginning column of  the  field.
  104. If  omitted,  column  1  is assumed.  If present, [:width] defines the
  105. field width in columns.  If width is omitted, the rest of  the  record
  106. is  assumed  to  be  part  of the key.  If no key field parameters are
  107. given,  the  entire  record  is   the   key   field.    When   sorting
  108. variable-length records, any key field which falls beyond the end of a
  109. particular record is treated as a null (zero length)  field  for  that
  110. record,  and  collates  low.   When  sorting fixed-length records, all
  111. defined fields must fall within the defined record length.
  112.  
  113.                         The /F<len> Parameter
  114.  
  115. The /F<len>  parameter  defines  the  record  length  for  a  file  of
  116. fixed-length  records.   All records in the input file MUST be exactly
  117. <len> bytes long.  The records need not (but may) be terminated with a
  118. CR/LF  sequence.  They may contain any data, even binary data, but the
  119. key fields must be ASCII strings.  Strings may be  terminated  with  a
  120. null (binary zero) character, or may be padded with trailing spaces to
  121. the full length of the field.  Note that QSORT  does  not  attempt  to
  122. support  Pascal  style  strings.  These are strings which begin with a
  123. character whose binary value is a character count.  This  is  followed
  124. by  <count>  characters  of  ASCII  data, which in turn is followed by
  125. random data out to the maximum length of the  string.   These  strings
  126. may  be used as key fields, but the programmer must insure that either
  127. the last real character is a null character, or the field is padded to
  128. its  full  length with spaces.  QSORT must be told that the key begins
  129. in the second character position (the first character of real data).
  130.  
  131.                        The /T[<tag>] Parameter
  132.  
  133. The /T[<tag>] parameter, if present, indicates that the  "records"  to
  134. be  sorted  may  be  more  than  a single line long.  If <tag> is also
  135. present, it defines a character to be used to tag the "end-of-record."
  136. If  <tag>  is not present, the first empty line terminates the record.
  137. For this purpose, "empty" means "no characters." A line containing but
  138. a  single  space  is NOT empty!  A line may be "tagged" by placing the
  139. <tag> character anywhere on the last line of a  logical  record.   The
  140. entire  line, including the tag character will appear as the last line
  141. of the record.
  142.  
  143. Note that the /F<len> and /T[<tag>] parameters are  incompatible,  and
  144. may not both be specified.
  145.  
  146.                            The /R Parameter
  147.  
  148. The  /R  parameter  is included for compatibility with DOS SORT and is
  149. redundant.  It reverses the  sense  of  sort  direction  for  all  key
  150. fields.
  151.  
  152.                            The /S Parameter
  153.  
  154. The /S parameter tells QSORT to make a statistics report to the screen
  155. at the end of a run.  The report is written to  the  "standard  error"
  156. device,  the  console, and may not be redirected.  The following is an
  157. actual statistics report "cut" from the screen after QSORT had  sorted
  158. a 1 mega-byte+ file:
  159.  
  160.      QSORT - Text Sort - Version 3.00
  161.      Copyright (c) 1985, 1986, 1987  - Ben Baker - All rights reserved
  162.  
  163.           10131 records sorted
  164.             146 bytes in longest record
  165.  
  166.          116744 sort phase comparisons
  167.           53771 merge phase comparisons
  168.  
  169.          170515 total comparisons
  170.            16.8 comparisons per input record
  171.  
  172.              21 temporary merge files created
  173.               2 merge passes
  174.             2.3 average passes over data
  175.  
  176.            6:00 elapsed time
  177.  
  178. The  first  two  numbers  are  self-explanatory.  The next two are the
  179. number of times two records were compared during the  sort  phase  and
  180. the merge phase respectively, followed by the total comparisons.
  181.  
  182. The  next number is total comparisons divided by the number of records
  183. in the input file.  If  there  is  no  merge  phase,  this  number  is
  184. typically  10  to 12.  If the file is large enough to require merging,
  185. it is 12 to 20, on average.  If it is much larger than 20, it  usually
  186. means  that  there is something unusual about your input file.  It may
  187. already be sorted, or there may  be  large  blocks  of  records  which
  188. compare  equal.  This can happen if you sort on, say column 50 and the
  189. input file contains a large number of records shorter than  50  bytes.
  190. In  this  case,  a  minor sort key at column 1 may significantly speed
  191. sorting.
  192.  
  193. The next two items are self-explanatory.  "Average passes  over  data"
  194. reflects  the  number  of times each record was read and written.  For
  195. short files not requiring a merge pass, this number will be 1.0.  When
  196. merging  is  needed,  the  last merge pass is the one which writes the
  197. output file and it must read and  write  every  record  exactly  once.
  198. Thus  when  only  one  merge  pass  is made, there will be exactly 2.0
  199. "average passes over data." In the above case  the  first  merge  pass
  200. processed about 30% of the records, hence the value of 2.3.
  201.  
  202. The above sort was performed on an IBM XT with two hard drives (C  and
  203. D).   The  input file was on C;  the temporary merge files were placed
  204. on D;  and the output file  was  written  to  C.   The  sort  of  a  1
  205. mega-byte file took six minutes flat.  With my Tiny Turbo  accelerator
  206. turned on, the same sort takes about 3:50.
  207.  
  208.                           The /?  Parameter
  209.  
  210. The  /?   parameter requests help or parameter evaluation.  When QSORT
  211. is executed with the /?  parameter alone, it lists a short description
  212. of  the  QSORT  parameters.   If  /?   is  entered  as  one of several
  213. parameters, QSORT will produce a short report on the screen describing
  214. the  sort  it would perform based on those parameters without actually
  215. doing a sort.
  216.  
  217. For example:
  218.  
  219.      QSORT /? /L5:12 /-3:2 /22 /T /R <INFILE.TXT >OUTFILE.TXT
  220.  
  221. requests  a  sort  on  a file of tagged records.  It defines three key
  222. fields, one of them inverted (-).  The /R parameter reverses the sense
  223. of  all  three fields.  Since redirection is specified, QSORT does not
  224. see or know about the names  of  the  files  it  will  sort.   The  /?
  225. parameter  requests a report, rather than a sort, and QSORT obligingly
  226. produces on the screen, the following:
  227.  
  228.      QSORT - Text Sort - Version 3.00
  229.      Copyright (c) 1985, 1986, 1987  - Ben Baker - All rights reserved
  230.  
  231.      With the present arguments, QSORT would sort from STDIN to STDOUT
  232.      Records are multiple lines ending with an empty line
  233.  
  234.      Key fields in descending order of importance are:
  235.        Pos   Len Type
  236.  
  237.          5    12 Lexical Descending
  238.          3     2 ASCII
  239.         22 65535 ASCII   Descending
  240.  
  241. The  third  field has an unspecified length.  The value "65535" merely
  242. means that this field extends to the end of each record.
  243.  
  244.  
  245. The  /M<len>  supported  in  earlier  versions  of  QSORT is no longer
  246. required, but will be accepted (and ignored) by QSORT.   There  is  no
  247. "hard-coded"  maximum record length in QSORT, but there is a practical
  248. limit.  At some time during every sort, the two longest records in the
  249. input  file must be compared.  Therefore, the two longest records must
  250. be able to fit together in the sort buffer.  The sum of their  lengths
  251. cannot  exceed about 50K -- not an altogether unreasonable limitation.
  252. QSORT can be shoe-horned into tighter memory and will run  if  it  can
  253. find  4K  for  a  sort buffer and 4K for an output buffer, but the two
  254. longest records must still fit in the sort buffer together.
  255.  
  256. Arguments  may  appear  in  any  order on the command line except that
  257. <in_file> must appear before  <out_file>,  and  /<key_spec>  arguments
  258. must appear in descending order of importance.
  259.  
  260.  
  261.                        --- Lexical Sorting ---
  262.  
  263. The  lexical  sorting  capability was borne out of my own need to sort
  264. word lists with mixed capitalization.  ASCII  sequence  produced  some
  265. bizarre  results  when  words  beginning  with 'Z' sorted before those
  266. beginning with  'a.'   Case-insensitive  sorting  wasn't  much  better
  267. because upper and lower case got mixed randomly.
  268.  
  269. The following table will illustrate what I mean:
  270.  
  271.      INPUT         ASCII          CASE           LEXICAL
  272.                                INSENSITIVE
  273.  
  274.      DeLaPort      Baker          Baker          Baker
  275.      Smith         Brown          brown          Brown
  276.      brown         DeAngelo       bRown          bRown
  277.      deLaPorte     DeLaPort       Brown          brown
  278.      Deangelo      Deangelo       Deangelo       DeAngelo
  279.      deAngelo      Deangelo       deangelo       Deangelo
  280.      Brown         DelaPort       Deangelo       Deangelo
  281.      smith         DelaPorte      deAngelo       deAngelo
  282.      delaPorte     Harry          DeAngelo       deangelo
  283.      DelaPort      Smith          delaPort       DeLaPort
  284.      DeAngelo      bRown          DelaPort       DelaPort
  285.      DelaPorte     brown          delaPort       delaPort
  286.      deangelo      deAngelo       DeLaPort       delaPort
  287.      Harry         deLaPorte      DelaPorte      DelaPorte
  288.      delaPort      deLaPorte      deLaPorte      deLaPorte
  289.      Baker         deangelo       delaPorte      deLaPorte
  290.      deLaPorte     delaPort       deLaPorte      delaPorte
  291.      Deangelo      delaPort       Harry          Harry
  292.      bRown         delaPorte      smith          Smith
  293.      delaPort      smith          Smith          smith
  294.  
  295. The first column is a list of names in arbitrary order.  The second is
  296. an   ASCII   sort   of   that   list.   Third  we  have  one  possible
  297. case-insensitive sort of the list.  The fourth column is what I really
  298. wanted.   It  is  sorted  the  way  these  words  would be sorted in a
  299. dictionary (or lexicon).  The third and fourth  columns  both  collect
  300. words  of identical spellings together, but in the third column, upper
  301. and lower case spellings are in  arbitrary  order,  while  the  fourth
  302. column places upper case spellings ahead of lower case spellings.
  303.  
  304. For  example,  the  two  occurrences  of Smith are widely separated in
  305. column 2 because one is capitalized and the other is  not.   Column  3
  306. brings the two together, but in the wrong order.  They might have been
  307. in the right order, but the order is strictly arbitrary.  In column 4,
  308. Smith  comes before smith, and lexical sorting will always put them in
  309. this order.
  310.  
  311. Lexical sorting is achieved by making case-insensitive comparisions of
  312. entire fields.  If the fields compare equal, an  ASCII  comparison  is
  313. made  to arbitrate ties.  In other words, when "lexical" fields in two
  314. records have  different  spellings,  the  case-insensitive  comparison
  315. determines  the  order  of  the  records.   When  "lexical" fields are
  316. spelled the same, the case-sensitive comparison determines  the  order
  317. of the records.
  318.  
  319. Lexical  fields are defined, as indicated above, by placing the letter
  320. 'L' immediately following the slant-bar (/) in <key_spec> definitions.
  321.  
  322. Lexical  sorting  can  be  very  useful when needed, but be aware that
  323. unnecessarily specifying lexical ordering may degrade  performance  of
  324. QSORT.
  325.  
  326.  
  327.                            --- Examples ---
  328.  
  329. Produce  a  sorted  directory  listing and display it on the console a
  330. screen's worth at a time:
  331.  
  332.      A>DIR | QSORT | MORE
  333.  
  334. This demonstrates the use of QSORT as a "filter" in a "pipe."  Produce
  335. a  directory  listing sorted by creation date and time, and display it
  336. on the console a screen's worth at a time:
  337.  
  338.      A>DIR | QSORT /30:2 /24:5 /39 /34:5 | MORE
  339.  
  340. The output of the DIR command is  piped  to  QSORT.   The  key  fields
  341. defined  are,  from  left  to right (major to minor), year (2 digits),
  342. month and day, AM/PM flag and time.  The output of QSORT is then piped
  343. to MORE for display.
  344.  
  345. Next,  replace  the  unsorted  FILE.TXT  with  the same data sorted in
  346. reverse order.  Use columns 10 to 16 as the sort key:
  347.  
  348.      A>QSORT FILE.TXT /-10:7
  349.            or
  350.      A>QSORT FILE.TXT /10:7 /R
  351.            or (SORT compatible)
  352.      A>QSORT FILE.TXT /R /+10
  353.  
  354. Next, perform a simple sort on a file with up to 240-byte records
  355.  
  356.      A>QSORT LARGE.REC /M240
  357.            or
  358.      A>QSORT LARGE.REC
  359.  
  360. Note that the "/M240" parameter is no  longer  needed,  but  will  not
  361. hurt.
  362.  
  363. GLOSS.TXT is an unsorted glossary of terms.  The term being defined by
  364. each  entry  appears  first,  followed by several lines of definition.
  365. The entries are separated by empty lines.  Produce GLOSS.SRT, a sorted
  366. version of the glossary:
  367.  
  368.      A>QSORT /T  <GLOSS.TXT >GLOSS.SRT        (with redirection)
  369.           or
  370.      A>QSORT /T   GLOSS.TXT  GLOSS.SRT        (without redirection)
  371.  
  372. A  lawyer  keeps a running log of his billable activities in TIME.LOG.
  373. The first line of each entry is "mm/dd/yy hh:mm account#."  He  always
  374. places  a tilde (~) in the last line of each entry.  He wishes to sort
  375. the log by account number, and by ascending date and time within  each
  376. account:
  377.  
  378.      QSORT  /16:7 /7:2 /1:5 /10:5 /T~  TIME.LOG
  379.  
  380. The directory of users for a bulletin board system is kept in a binary
  381. file of fixed-length records 180 bytes  long.   The  user  name  is  a
  382. 26-character  field beginning in the first position and the city/state
  383. field is a 16-character field  beginning  in  the  fortieth  position.
  384. Sort the file by city/state and name.
  385.  
  386.      QSORT /F180 /40:16 /1:26 USER.BBS
  387.  
  388.                      --- Implementation Notes ---
  389.  
  390. QSORT  is  intended  as  an  enhanced replacement for DOS SORT.  It is
  391. nearly fully upward compatible, but provides  much  more  flexibility.
  392. Multiple  sort  keys  may  be specified, a pseudo in-place sort may be
  393. performed and files and/or records of any size may be sorted  provided
  394. only that there is sufficient disk space for work files and the output
  395. file.  QSORT uses the "quick sort" algorithm, which  cannot  guarantee
  396. the  order  of  records  whose  keys  are  all equal.  This is the one
  397. "incompatibility" with DOS SORT, which retains the original  order  of
  398. records  when  its only key compares equal.  This is important to SORT
  399. because it must be invoked multiple times to  effect  a  multiple  key
  400. sort.   With  QSORT,  you  only sort once and there are usually enough
  401. keys available to insure you get the order you want the first time.
  402.  
  403. QSORT uses a sort buffer of about 50K bytes  and will fill the  buffer
  404. as full as possible, and then sort  the contents of the buffer.  If it
  405. has reached the end of the input file and has not  yet  generated  any
  406. work files, the contents of the buffer are written to the output file,
  407. completing the sort operation.
  408.  
  409. If the input file is too large to fit into the sort buffer, as much of
  410. the  input  file  as  possible  is  read into the buffer, sorted, then
  411. written to a temporary work file.  This process is  repeated  as  many
  412. times  as  necessary  to  process  the  entire  input  file, each time
  413. creating a new work file for the sorted output.
  414.  
  415. Upon completion of the "sort phase," QSORT  begins  a  "merge  phase."
  416. Each  work  file  is  a  sorted sub-set of the input file.  Thus, work
  417. files may be read  sequentially  and  combined  to  produce  a  sorted
  418. output.   QSORT  will  open as many work files as DOS permits (more on
  419. this later).  If all the remaining  work  files  can  be  opened,  the
  420. sorted  result  is  written to the output file.  Otherwise, a new work
  421. file is created and another merge pass  will  be  required.   On  each
  422. merge  pass,  the  number  of work files is reduced and eventually all
  423. remaining work files will be opened and the sorted output file will be
  424. written completing the sort operation.
  425.  
  426. QSORT  is  smart  enough  to  never have just one work file remaining,
  427. which would require an unnecessary copy operation.  In fact, QSORT  is
  428. smarter  than  just  that in its handling of the merge phase.  If more
  429. than one merge pass is required, all the data merged during the  first
  430. pass  will  have to be merged again, so QSORT attempts to minimize the
  431. first pass.  For example, if QSORT discovers it may only open 15 files
  432. at  a  time,  and there are 16 temporary files, it will only merge two
  433. files on the first pass, creating a 17th file as it does.  Then in the
  434. second  pass, it will merge all 15 remaining files to the output file.
  435. The less data it processes twice, the faster it performs the sort!
  436.  
  437. With nothing else to guide it, QSORT places its temporary files in the
  438. default directory.  Either of two "environment variables" can override
  439. this.  (See your DOS manual for information on  environment  variables
  440. and the SET command.) The command:
  441.  
  442.      SET QSTMP=<path>        or
  443.      SET TMP=<path>
  444.  
  445. will  define a path for QSORT to use for its temporaries.  QSORT first
  446. looks for the environment variable QSTMP.  If it does not exist, QSORT
  447. next looks for TMP.  TMP is a de facto standard used by many programs,
  448. and is usually defined in your AUTOEXEC.BAT  batch  file.   You  might
  449. have TMP specifying a 64K RAM disk to speed up your compiler.  In this
  450. case, an attempt to sort a 100K file is  doomed  to  failure.   Rather
  451. than  redefine  TMP,  you  may define QSTMP to force QSORT to use some
  452. directory on your hard disk.  In fact:
  453.  
  454.      SET QSTMP=.
  455.  
  456. tells QSORT to always use the default directory anyway!
  457.  
  458. QSORT, to work properly, needs enough space on the output disk to hold
  459. the output file.  Even if the input file is to be deleted and  resides
  460. in  the  same  directory, that is not done until after the output file
  461. has been successfully written.  If one merge  pass  is  required,  the
  462. disk  QSORT uses for temporaries should have about 10% more space than
  463. the size of the input file for temporary merge files.   If  more  than
  464. one  merge  pass  will  be required, allow about twice the size of the
  465. input file as temporary merge file space.
  466.  
  467. One of the advantages of controlling where QSORT places its  temporary
  468. files  is  to  insure adequate space for them.  A second is speed.  If
  469. the temporary files can be placed on a separate disk  from  the  input
  470. and  output files, disk seeking is minimized and performance improved.
  471.  
  472. Each time QSORT must create a new temporary merge file, the  data  put
  473. into  it will be processed again.  Obviously, the more files QSORT can
  474. open during the merge phase, the fewer times it will  have  to  handle
  475. each  record  and  the  faster  it  can  sort  large files.  If DOS is
  476. properly pre-conditioned, QSORT can have  up  to  15  temporary  merge
  477. files  open  at once, and very large files can be sorted with just one
  478. sort pass and one merge pass.  Unfortunately, that capability  is  not
  479. automatic.
  480.  
  481. DOS  has a fixed number of file "handles" that it associates with open
  482. files.  The default number is eight, but DOS opens five  of  them  for
  483. standard  input, standard output, standard error, standard printer and
  484. standard auxiliary device.  That leaves three  for  merging.   A  250K
  485. input  file  would  produce  five temporary merge files and that would
  486. take three merge passes;  merge two into one, leaving four;  merge two
  487. into one leaving three;  and finally merge three into the output file.
  488. In the process,  QSORT must read and write about 80% of the file twice
  489. during the merge phase.
  490.  
  491. Worse yet, since you need at least three handles for merging,  if  you
  492. have resident programs that have open files, you can't merge at all!
  493.  
  494. DOS can be told to set aside more space for file handles.  Each handle
  495. is only 39 bytes and it's memory very well  spent.   One  process  can
  496. have  a  maximum  of  20  handles open at one time, but since resident
  497. processes may be using handles, I recommend 25 to 35.  To do this, the
  498. root  directory of the DISK OR DISKS YOU BOOT FROM must contain a file
  499. named CONFIG.SYS.  If your boot disk(s) already contains a CONFIG.SYS,
  500. edit it, or if not, create it to contain the following line:
  501.  
  502.      FILES=25        (or more)
  503.  
  504. While  we're  at it, let's add one more thing to CONFIG.SYS which will
  505. improve the performance of QSORT and many other programs as well.  DOS
  506. provides, by default, two disk buffers.  These are the buffers it uses
  507. to do its disk reads and writes.  During the  merge  phase  QSORT  may
  508. have many files open at once, reading from them in more or less random
  509. order.  DOS may have to read the same physical sector several times to
  510. get  all  its  data.   But  DOS can remember what's in each buffer and
  511. where it came from, and will not re-read a sector it already has in  a
  512. buffer.   DOS needs 528 bytes for each buffer.  I recommend 20 buffers
  513. to make QSORT perform well under the most  adverse  conditions.   This
  514. will  require an additional 9504 bytes or slightly more than 9K, again
  515. memory well spent, so we add to CONFIG.SYS the following line:
  516.  
  517.      BUFFERS=20
  518.  
  519. See your DOS manual for more information on CONFIG.SYS.
  520.  
  521.  
  522. I hope you find this program useful.  Your  comments  and  suggestions
  523. are  welcome.   My  address  is  at  the  top of this file.
  524.